﻿using LightCAD.MathLib;
using LightCAD.Three;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using verb.geom;

namespace TestWinform
{
    public static class V3
    {
        public static BufferGeometry  toThreeGeometry (this verb.geom.NurbsCurve curve)
        {
            return tessellateCurve(curve);
        }

        public static BufferGeometry toThreeGeometry(this verb.geom.NurbsSurface surface)
        {
            return tessellateSurface(surface);
        }

        public static Vector3[] asVector3(Array<object> pts)
        {
            var vlist = new List<Vector3>();
            for(var i=0;i<pts.length;i++)
            {
                var x = pts[i] as Array<double>;
                vlist.Add( new Vector3(x[0], x[1], x[2]));
            }
            return vlist.ToArray();
        }

        public static BufferGeometry asGeometry(Vector3[] threePts)
        {
            var geometry = new BufferGeometry();
            geometry.setFromPoints(threePts);
            return geometry;
        }
        private static BufferGeometry tessellateCurve(NurbsCurve curve)
        {
            var geometry = new BufferGeometry();
            geometry.setFromPoints(asVector3(curve.tessellate(null)));
            return geometry;
        }

        private static BufferGeometry tessellateSurface(NurbsSurface srf)
        {
            var tess = srf.tessellate(null);

            var geometry = new BufferGeometry();

            geometry.setFromPoints( asVector3(tess.points));
            var idxList = new List<int>();
            for(var i=0;i< tess.faces.length;i++)
            {
                var face = tess.faces[i];
                idxList.AddRange((face as Array<int>).__a);
            };
            geometry.setIndex(idxList.ToArray());

            var norList = new List<double>();
            for(var i = 0; i < tess.normals.length; i++)
            {
                var nor = (tess.normals[i] as Array<double>).__a;
                norList.AddRange(new double[] { nor[0], nor[1], nor[2] });
            }
            geometry.setAttribute("normal", new Float32BufferAttribute(norList.ToArray(), 3));

            return geometry;
        }
        internal static Array<double> P(double v1, double v2, double v3)
        {
            return new Array<double>(new double[] { v1, v2, v3 });
        }
        internal static Array<int> V(int v1, int v2, int v3)
        {
            return new Array<int>( new int[] { v1, v2, v3 });
        }
        internal static Array<object> Arr(params object[] items)
        {
            return new Array<object>(items);
        }

        internal static Vector3 V(Array<double> rp)
        {
            return new Vector3(rp[0], rp[1], rp[2]);
        }
    }
}
